﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FileExplorer
{
    /// <summary>
    /// 数据类型转换工具类，文件与byte数组互转、Image与byte数组互转、byte数组与String互转、Icon与Image互转、Icon与String互转、Image与String互转、Image与Bitmap互转
    /// </summary>
    public class RecodeTool
    {
        # region 文件与byte数组互转

        /// <summary>
        /// 将文件转换为byte数组
        /// </summary>
        /// <param name="path">文件地址</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] File2Bytes(string path)
        {
            if (!File.Exists(path)) return new byte[0];

            FileInfo fi = new FileInfo(path);
            byte[] buff = new byte[fi.Length];

            FileStream fs = fi.OpenRead();
            fs.Read(buff, 0, Convert.ToInt32(fs.Length));
            fs.Close();

            return buff;
        }

        /// <summary>
        /// 将byte数组转换为文件并保存到指定地址
        /// </summary>
        /// <param name="buff">byte数组</param>
        /// <param name="savepath">保存地址</param>
        public static void Bytes2File(byte[] buff, string savepath)
        {
            if (File.Exists(savepath)) File.Delete(savepath);

            FileStream fs = new FileStream(savepath, FileMode.CreateNew);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(buff, 0, buff.Length);
            bw.Close();
            fs.Close();
        }

        # endregion


        # region Image与byte数组互转

        /// <summary>
        /// 将Image转化为byte数组
        /// </summary>
        public static byte[] Image2Bytes(Image image, ImageFormat imageFormat = null)
        {
            if (imageFormat == null) imageFormat = ImageFormat.Png;

            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            image.Save(stream, imageFormat);
            byte[] bytes = stream.ToArray();

            return bytes;
        }

        /// <summary>
        /// 从byte数组创建Image
        /// </summary>
        public static Image Bytes2Image(byte[] bytes)
        {
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            stream.Write(bytes, 0, bytes.Length);
            Image image = Image.FromStream(stream);

            return image;
        }

        /// <summary>
        /// 将Image转化为byte数组,使用缓存文件中转
        /// </summary>
        public static byte[] Image2Bytes_tmpFile(Image image, ImageFormat imageFormat = null)
        {
            if (imageFormat == null) imageFormat = ImageFormat.Jpeg;
            String tmpFilePath = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Ticks + ".stream";
            image.Save(tmpFilePath, imageFormat);   // 保存图像到文件

            byte[] bytes = File2Bytes(tmpFilePath); // 从文件中获取字节数组
            if (File.Exists(tmpFilePath)) File.Delete(tmpFilePath); //删除文件

            return bytes;
        }

        # endregion


        # region byte数组与String互转

        /// <summary>
        /// 将byte数组，转化为字符串形式（每个字节转化为两个字母）
        /// </summary>
        public static string Bytes2String(byte[] B)
        {
            StringBuilder Str = new StringBuilder();
            foreach (byte b in B)
            {
                string tmp = "" + (char)('a' + (b / 16)) + (char)('a' + (b % 16));
                Str.Append(tmp);
            }
            return Str.ToString();
        }

        /// <summary>
        /// 将字母字符串还原为byte数组(需与Bytes2String配对使用）
        /// </summary>
        public static byte[] String2Bytes(string data)
        {
            byte[] B = new byte[data.Length / 2];
            char[] C = data.ToCharArray();

            for (int i = 0; i < C.Length; i += 2)
            {
                byte b = (byte)((C[i] - 'a') * 16 + (C[i + 1] - 'a'));
                B[i / 2] = b;
            }

            return B;
        }

        # endregion


        # region Icon与Image互转

        /// <summary>
        /// Icon转化为Image
        /// </summary>
        public static Image Icon2Image(Icon icon)
        {
            Bitmap bitmap = icon.ToBitmap();
            return bitmap;
        }

        /// <summary>
        /// Image转化为Icon
        /// </summary>
        public static Icon Image2Icon(Image image)
        {
            Bitmap bitmap = (Bitmap)image;
            IntPtr ptr = bitmap.GetHicon();
            Icon icon = Icon.FromHandle(ptr);
            return icon;
        }

        # endregion


        # region Icon与String互转

        /// <summary>
        /// Icon转化为字符串
        /// </summary>
        public static string Icon2String(Icon icon)
        {
            Bitmap bitmap = icon.ToBitmap();
            byte[] bytes = Image2Bytes(bitmap);
            String Str = Bytes2String(bytes);
            return Str;
        }

        /// <summary>
        /// String转化为Icon
        /// </summary>
        public static Icon String2Icon(string iconStr)
        {
            byte[] bytes = String2Bytes(iconStr);
            Bitmap bitmap = (Bitmap)Bytes2Image(bytes);
            Icon icon = Icon.FromHandle(bitmap.GetHicon());
            return icon;
        }

        # endregion


        # region Image与String互转

        /// <summary>
        /// Image转化为字符串
        /// </summary>
        public static string Image2String(Image image)
        {
            byte[] bytes = Image2Bytes(image);
            String Str = Bytes2String(bytes);
            return Str;
        }

        /// <summary>
        /// String转化为Image
        /// </summary>
        public static Image String2Image(string imageStr)
        {
            byte[] bytes = String2Bytes(imageStr);
            Image image = Bytes2Image(bytes);
            return image;
        }

        # endregion


        # region Image与Bitmap互转

        /// <summary>
        /// Image转Bitmap
        /// </summary>
        public static Bitmap Image2Bitmap(Image image)
        {
            return (Bitmap)image;
        }

        /// <summary>
        /// Bitmap转Image
        /// </summary>
        public static Image Bitmap2Image(Bitmap bitmap)
        {
            return bitmap;
        }

        # endregion

    }
}
